package com.example.myproject.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Key;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Enumeration;
import java.util.Vector;

/***
 * 按照v9的密码加解密方式对应的加解密类 来源:http://wenku.baidu.com/link?url=dlu-h6ipSjt3fbltnL-
 * KG8Qa49R6iCT0NQ6uR_N58jSLdqXkPJIfbqIbBFZ6VV1y_1mCZyoov2XVrFHNTy2cY99iKyHC34FWb60g1Qs7Ltm
 * 
 * @author chains
 * 
 */
public class CryptoUtil {

    protected final static Log log = LogFactory.getLog(CryptoUtil.class);

	/*
	 * private static final byte[] DESkey = { (byte) 0x15, (byte) 0xE7, (byte)
	 * 0xA1, (byte) 0x22, (byte) 0x96, (byte) 0x8B, (byte) 0x24, (byte) 0xFA
	 * };// 设置密钥，略去
	 */
	private static final byte[] DESkey = { 102, 16, (byte) 93, (byte) 156, 78,
			4, (byte) 218, 32 };

	/*
	 * private static final byte[] DESIV = { (byte) 0xCE, (byte) 0x35, (byte)
	 * 0x5, (byte) 0xD, (byte) 0x98, (byte) 0x91, (byte) 0x8, (byte) 0xA };//
	 * 设置向量，略去
	 */
	private static final byte[] DESIV = { 55, 103, (byte) 246, 79, 36, 99,
			(byte) 167, 3 };// 设置向量，略去

	static AlgorithmParameterSpec iv = null;// 加密算法的参数接口，IvParameterSpec是它的一个实现
	private static Key key = null;
	/* 初始化 */
	static {
		try {
			DESKeySpec keySpec = new DESKeySpec(DESkey);// 设置密钥参数
			iv = new IvParameterSpec(DESIV);// 设置向量
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 获得密钥工厂
			key = keyFactory.generateSecret(keySpec);// 得到密钥对象
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 加密
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static String encode(String data) {
		try {
			Cipher enCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");// 得到加密对象Cipher
			enCipher.init(Cipher.ENCRYPT_MODE, key, iv);// 设置工作模式为加密模式，给出密钥和向量
			byte[] pasByte = enCipher.doFinal(data.getBytes("utf-8"));
			BASE64Encoder base64Encoder = new BASE64Encoder();
			return base64Encoder.encode(pasByte);
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

	/**
	 * 解密
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static String decode(String data) {
		try {
			Cipher deCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
			deCipher.init(Cipher.DECRYPT_MODE, key, iv);
			BASE64Decoder base64Decoder = new BASE64Decoder();
			byte[] pasByte = deCipher.doFinal(base64Decoder.decodeBuffer(data));
			return new String(pasByte, "UTF-8");
		} catch (Exception e) {
//			e.printStackTrace();
            log.error(e);
			return "";
		}
	}

	/**
	 * 解密房友或者v9加密方式的字符串
	 *(目前仅支持房友或者v9加密这两种加密方式的字符串)
	 * 如果没有解密成功,则返回原字符串
	 * @author chains
	 */
	public static String decodeStr(String encodeStr) {
		if (encodeStr == null || encodeStr.replaceAll(" ", "").trim().equals("")) {//空字符串
			return encodeStr;
		}
		//如果以XXXX或者MMMM开头,则我们认为是房友的加密方式
		else if (encodeStr.startsWith("XXXX") || encodeStr.startsWith("MMMM")|| encodeStr.startsWith("KKKK")) {
			String beforeEncodeStr=encodeStr;//解密之前的字符串
			//encodeStr=(CrackUtil.doCrackPhone(encodeStr));//解密
			if(encodeStr.equals("")){//如果返回空则没有解密成功,返回原字符串
				return beforeEncodeStr;
			}else{
				return encodeStr;
			}
		}
		//否则我们认为是v9的加密方式
		else {
			String beforeEncodeStr=encodeStr;//解密之前的字符串
			encodeStr=(CryptoUtil.decode(encodeStr));//解密
			if(encodeStr.equals("")){//如果返回空则没有解密成功,返回原字符串
				return beforeEncodeStr;
			}else{
				return encodeStr;
			}
		}
	}

	//0085296700123
	public static void main(String[] args) throws Exception {

		Long a = null;
		if(a!=null){
			System.out.println("23");
		}else{
			System.out.println("456");
		}

		long startTime = System.currentTimeMillis();
		System.out.println("加密:" + CryptoUtil.encode("0831Z5sso"));
		System.out.println("加密时间:"  + (System.currentTimeMillis() - startTime));
		startTime = System.currentTimeMillis();
		System.out.println("解密:" + CryptoUtil.decode("HbnrPANT1FsP3Bkr+aBFDg=="));
		System.out.println("解密时间:"  + (System.currentTimeMillis() - startTime));
	}
}